package io.gitee.guoguoleo.utils;

import cn.hutool.core.map.MapUtil;
import io.gitee.guoguoleo.annotation.JokerField;
import io.gitee.guoguoleo.annotation.JokerIgnore;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class EntityUtil {

    /**
     * 将map转成实体，map中的key必须与实体中的属性名相同才可以转换成功
     *
     * @param list       list
     * @param entityType 类
     * @return list结果
     */
    public static <T> List<T> coverToEntityList(List<Map<String, Object>> list, Class<T> entityType) {
        return list.stream().map(map -> coverToEntity(map, entityType)).collect(Collectors.toList());
    }

    /**
     * 将map转成实体，map中的key必须与实体中的属性名相同才可以转换成功
     *
     * @param entityMap  map
     * @param entityType 类
     * @return 泛型对象
     */
    public static <T> T coverToEntity(Map<String, Object> entityMap, Class<T> entityType) {
        Map<String, Object> resultMap = MapUtil.toCamelCaseMap(entityMap);
        try {
            T obj = entityType.getConstructor().newInstance();
            Map<String, Field> fieldMap = getFieldMap(entityType);

            for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
                Field field = entry.getValue();
                Object value = resultMap.get(field.getName());
                if (value == null) {
                    continue;
                }
                field.setAccessible(true);

                if (field.getType().getName().equals("java.lang.String")) {
                    if (StringUtils.isNotBlank(value.toString())) {
                        field.set(obj, value.toString());
                        continue;
                    }
                }

                if (field.getType().getName().equals("java.lang.Long")) {
                    if (StringUtils.isNotBlank(value.toString())) {
                        field.set(obj, Long.parseLong(value.toString()));
                        continue;
                    }
                }

                if (field.getType().getName().equals("java.lang.Integer")) {
                    if (value.toString().equals("true") || value.toString().equals("false")) {
                        field.set(obj, value.toString().equals("true") ? 1 : 0);
                        continue;
                    }
                }


                try {
                    field.set(obj, value);
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage());
                }
            }
            return obj;
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 得到某个类的属性map key为属性名，value为属性
     *
     * @param entityClass 类
     * @return 字段名称和Field的map
     */
    public static Map<String, Field> getFieldMap(Class<?> entityClass) {
        Field[] fields = entityClass.getDeclaredFields();
        Map<String, Field> fieldsMap = new ConcurrentHashMap<>();
        for (Field field : fields) {
            JokerIgnore jokerIgnore = field.getAnnotation(JokerIgnore.class);
            if (jokerIgnore != null && jokerIgnore.ignore()) {
                continue;
            }
            fieldsMap.put(field.getName(), field);
        }
        Class<?> superclass = entityClass.getSuperclass();
        if (superclass != null) {
            fieldsMap.putAll(getFieldMap(superclass));
        }
        return fieldsMap;
    }

}
